package org.hongqi.common.senpec.sys.role;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hongqi.common.senpec.base.mybatisplus.IBaseServiceImpl;
import org.hongqi.common.senpec.base.sevlet.Result;
import org.hongqi.common.senpec.base.utils.ObjectsUtil;
import org.hongqi.common.senpec.sys.user.UserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl extends IBaseServiceImpl<RoleMapper, Role> implements RoleService {

    private final RoleMapper roleMapper;
    private final UserMapper userMapper;

    @Override
    public Result<Role> mySave(Role role) {
        if (ObjectsUtil.noNull(roleMapper.selectByRoleName(role.getRoleName()))) {
            return Result.error(new Role()).msg("角色《" + role.getRoleName() + "》已存在。");
        }
        int insertedNum = roleMapper.insert(role);
        return insertedNum > 0 ? Result.ok(roleMapper.selectById(role.getId())) : Result.error(role);
    }

    @Override
    public Result<?> myRemoveById(Long id) {
        int deletedNum = roleMapper.deleteById(id);
        return deletedNum > 0 ? Result.ok() : Result.error();
    }

    @Override
    public Result<Role> myUpdateById(Role role) {
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Role::getRoleName, role.getRoleName());
        lambdaQueryWrapper.ne(Role::getId, role.getId());
        Role roleSelected = roleMapper.selectOne(lambdaQueryWrapper);
        if (ObjectsUtil.noNull(roleSelected)) {
            return Result.error(new Role()).msg("角色《" + role.getRoleName() + "》已存在。");
        }
        int updatedNum = roleMapper.updateById(role);
        return updatedNum > 0 ? Result.ok(roleMapper.selectById(role)) : Result.error(role);
    }

    @Override
    public Result<Role> myGetById(Long id) {
        Role role = roleMapper.selectById(id);
        if (ObjectsUtil.isNull(role)) {
            return Result.error(new Role());
        } else {
            return Result.ok(role);
        }
    }

    @Override
    public Result<IPage<Role>> myListObjsWithPage(Role role) {
        IPage<Role> page = new Page<>(role.getCurrent(), role.getSize());
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(role.getRoleName()), Role::getRoleName, role.getRoleName());
        IPage<Role> iPage = roleMapper.selectPage(page, lambdaQueryWrapper);
        List<Role> roles = iPage.getRecords();
        roles.forEach(item -> {
            item.setCreatorObj(userMapper.selectById(item.getCreator()));
            item.setUpdaterObj(userMapper.selectById(item.getUpdater()));
        });
        iPage.setRecords(roles);
        return Result.ok(iPage);
    }

    @Override
    public Result<Collection<Role>> myListObjsWithoutPage(Role role) {
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.isNotBlank(role.getRoleName()), Role::getRoleName, role.getRoleName());
        List<Role> roles = roleMapper.selectList(lambdaQueryWrapper);
        roles.forEach(item -> {
            item.setCreatorObj(userMapper.selectById(item.getCreator()));
            item.setUpdaterObj(userMapper.selectById(item.getUpdater()));
        });
        return Result.ok(roles);
    }

    @Override
    public Result<Collection<Role>> myListObjsByUserId(Long userId) {
        Collection<Role> roles = roleMapper.selectRolesByUserId(userId);
        return Result.ok(roles);
    }

    @Override
    public Result<Collection<Role>> myUpdateRoleIdByUserId(Long roleId, Long userId) {
        Collection<Role> roles = roleMapper.selectRolesByUserId(userId);
        boolean match = roles.stream().anyMatch(role -> Objects.equals(role.getId(), roleId));
        Integer num = 0;
        if (match) {
            num = roleMapper.deleteRoleIdByUserId(userId, roleId);
        } else {
            num = roleMapper.insertRoleIdByUserId(userId, roleId);
        }
        roles = roleMapper.selectRolesByUserId(userId);
        return num > 0 ? Result.ok(roles) : Result.error(roles);
    }

}
